package com.cmccsi.uc.redis;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.ScanResult;
import redis.clients.jedis.exceptions.JedisConnectionException;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.thn.netty.chat.server.ExecRedisCmdErr;
import com.thn.netty.chat.util.RedisConnPool;

public class RedisCsync implements IRedisCsync {	

	private Date m_lastPingTime;

	private static final Logger LOGGER = Logger.getLogger(RedisCsync.class.getName());
	
	
	public RedisCsync()
	{

	}
	
	private	int testPingCmd() {
		return 0;
	}		//测试是否能ping通服务器
	private void freeRedisConn() {
	}

	//根据key值，获取链表中Long类型的值
	private int getLongTypeListsFromRedis( String szCmd, List<Long>  list, ExecRedisCmdErr  rtValue ) {		
		list.clear();
		int idx = szCmd.indexOf("LRANGE" );
		if ( idx == -1 )
		{
			rtValue.setSzErrorCodeStr("invalid command!");
			rtValue.setErrorCode(-1);
			return -1;
		}
		List<String> values=new ArrayList<String>();
		{
			
			Jedis sc = null;
			boolean broken = false;
			try {
				sc = RedisConnPool.getJedis();
				String[] keys=szCmd.split(" ");				
				values=sc.lrange(keys[1], Long.parseLong(keys[2]), Long.parseLong(keys[3]));
			} catch (JedisConnectionException e) {
				LOGGER.error(e.getMessage(), e);				
				rtValue.setSzErrorCodeStr(e.getMessage());
				rtValue.setErrorCode(-1);
				broken = true;				
			} finally {
				RedisConnPool.returnJedis(sc, broken);
			}
			if(values.isEmpty())
			{
				return -1;
			}
			
			for ( int i = 0; i < values.size(); i++ )
			{
				String szMemberId = values.get(i);
				long ulMemberId =Long.parseLong(szMemberId);
				list.add(ulMemberId );
			}			
			return 0;
		}
	}

	//根据key值，获取链表中Strng类型的值
	private int getStringTypeListsFromRedis( String szCmd, List<String> szList, ExecRedisCmdErr  rtValue ) {
		szList.clear();
		int idx = szCmd.indexOf("LRANGE" );
		if ( idx == -1 )
		{
			rtValue.setSzErrorCodeStr("invalid command!");
			rtValue.setErrorCode(-1);
			return -1;
		}

		{
			List<String> values=new ArrayList<String>();
			{
				
				Jedis sc = null;
				boolean broken = false;
				try {
					sc = RedisConnPool.getJedis();
					String[] keys=szCmd.split(" ");				
					values=sc.lrange(keys[1], Long.parseLong(keys[2]), Long.parseLong(keys[3]));
				} catch (JedisConnectionException e) {
					LOGGER.error(e.getMessage(), e);				
					rtValue.setSzErrorCodeStr(e.getMessage());
					rtValue.setErrorCode(-1);
					broken = true;				
				} finally {
					RedisConnPool.returnJedis(sc, broken);
				}
				if(values.isEmpty())
				{
					return -1;
				}
				
				for ( int i = 0; i < values.size(); i++ )
				{
					String szVErr = values.get(i);
					szList.add(szVErr );
				}			
				return 0;
			}
		}
	}

	//根据key值，获取uCount个链表中string类型的值,如果少于uCount个，返回实际数量
	private int getStringTypeListsFromRedisByCount( String szCmd, String[] strResult, int  uCount, ExecRedisCmdErr  rtValue ) {
		int idx = szCmd.indexOf("LRANGE" );
		if ( idx == -1 )
		{
			rtValue.setSzErrorCodeStr("invalid command!");
			rtValue.setErrorCode(-1);
			return -1;
		}
			List<String> values=new ArrayList<String>();
			{
				
				Jedis sc = null;
				boolean broken = false;
				try {
					sc = RedisConnPool.getJedis();
					String[] keys=szCmd.split(" ");				
					values=sc.lrange(keys[1], Long.parseLong(keys[2]), Long.parseLong(keys[3]));
				} catch (JedisConnectionException e) {
					LOGGER.error(e.getMessage(), e);				
					rtValue.setSzErrorCodeStr(e.getMessage());
					rtValue.setErrorCode(-1);
					broken = true;				
				} finally {
					RedisConnPool.returnJedis(sc, broken);
				}
				if(values.isEmpty())
				{
					return -1;
				}				
				for ( int i = 0; i < values.size(); i++ )
				{
					String strv = values.get(i);
					strResult[i]=strv;
				}			
				return 0;
			}
	}

	//根据key值，获取set中Long类型的值
	private int getLongTypeSetFromRedis( String szCmd, List<Long>  list, ExecRedisCmdErr  rtValue ) {
		
		list.clear();
		
		int idx = szCmd.indexOf("sscan" );
		if ( idx == -1 )
		{
			rtValue.setSzErrorCodeStr("invalid command!");
			rtValue.setErrorCode(-1);
			return -1;
		}
		StringBuffer  szIndex=new StringBuffer ("0");
		do 
		{
			String szCmdFinal=szCmd;
			szCmdFinal += " ";
			szCmdFinal += szIndex.toString();
			int rslt = getLongTypeSetFromRedisIn( szCmdFinal, list, szIndex, rtValue );
			if (rslt != 0) {
				LOGGER.warn("CSyncR::getLongTypeSetFromRedis rslt:"+rslt);
			}
		} while ( szIndex.toString() != "0" );
		return 0;
	}

	//获取hash类型中全部的key值，并以uunsigned long 类型返回
	private int getAllLongTypeHashKeysFromRedis( String szCmd, List<Long>  list, ExecRedisCmdErr  rtValue ) {
		list.clear();
		{	
			
			int idx = szCmd.indexOf( "HKEYS" );
			if ( idx == -1 )
			{
				rtValue.setSzErrorCodeStr("invalid command!");
				rtValue.setErrorCode(-1);
				return -1;
			}
			
			Set<String> values=new HashSet<String>();
			{				
				Jedis sc = null;
				boolean broken = false;
				try {
					sc = RedisConnPool.getJedis();
					String[] keys=szCmd.split(" ");				
					values=sc.hkeys(keys[1]);
				} catch (JedisConnectionException e) {
					LOGGER.error(e.getMessage(), e);				
					rtValue.setSzErrorCodeStr(e.getMessage());
					rtValue.setErrorCode(-1);
					broken = true;				
				} finally {
					RedisConnPool.returnJedis(sc, broken);
				}
				if(values.isEmpty())
				{
					return -1;
				}	
				
				   Iterator it=values.iterator();
			       while(it.hasNext())
			       {
			    	   long o=Long.valueOf(it.next().toString());
			           list.add(o);
			       }
						
				return 0;
			}
		}
	}
	//使用hscan的方式，获取数据中全部的内容, 
	private int getStringTypeHashsFromRedis( String szCmd, Map<String,String> map, StringBuffer szIndex,
		ExecRedisCmdErr  rtValue ) {
		map.clear();
		{
			//HSCAN
			int idx = szCmd.indexOf( "HSCAN" );
			if ( idx == -1 )
			{
				rtValue.setSzErrorCodeStr("invalid command!");
				rtValue.setErrorCode(-1);
				return -1;
			}
			 ScanResult<Map.Entry<String, String>> scanResult = null;
			{				
				Jedis sc = null;
				boolean broken = false;
				try {
					sc = RedisConnPool.getJedis();
					String[] keys=szCmd.split(" ");				
					scanResult=sc.hscan(keys[1], szIndex.toString());
					szIndex.delete(0, szIndex.length());
					szIndex.append(scanResult.getCursor());
				} catch (JedisConnectionException e) {
					LOGGER.error(e.getMessage(), e);				
					rtValue.setSzErrorCodeStr(e.getMessage());
					rtValue.setErrorCode(-1);
					broken = true;				
				} finally {
					RedisConnPool.returnJedis(sc, broken);
				}
				List<Map.Entry<String, String>> listV=scanResult.getResult();
				if(listV.isEmpty())
				{
					return -1;
				}	
				for ( int i = 0; i < listV.size(); i ++  )
				{
					map.put(listV.get(i).getKey(), listV.get(i).getValue());
				}						
				return 0;
			}
		}
	}
	//使用hvals的方式，获取以逗号隔开的字符串值
	private int getStringValsHashsFromRedis( String szCmd, StringBuffer  strVals, 
		ExecRedisCmdErr  rtValue ) {
		
		//HVALS
		int idx = szCmd.indexOf( "HVALS" );
		if ( idx == -1 )
		{
			rtValue.setSzErrorCodeStr("invalid command!");
			rtValue.setErrorCode(-1);
			return -1;
		}		

		 List<String> values = new ArrayList<String>();
			{				
				Jedis sc = null;
				boolean broken = false;
				try {
					sc = RedisConnPool.getJedis();
					String[] keys=szCmd.split(" ");				
					values=sc.hvals(keys[1]);
				} catch (JedisConnectionException e) {
					LOGGER.error(e.getMessage(), e);				
					rtValue.setSzErrorCodeStr(e.getMessage());
					rtValue.setErrorCode(-1);
					broken = true;				
				} finally {
					RedisConnPool.returnJedis(sc, broken);
				}
				if(values.isEmpty())
				{
					return -1;
				}
				strVals.delete(0, strVals.length());
				for ( int i = 0; i < values.size(); i ++  )
				{
					String strVals0=values.get(i);
					if (i > 0)
						strVals0 += ",";
					strVals.append(strVals);
				}						
				return 0;
			}
	}

	private int deleteUserSessionInternal( String userId, ExecRedisCmdErr  rtValue ) {
		String szCmd = "HDEL usersession " + userId;
		int rslt = execCmd2Redis( szCmd, rtValue );
		return rslt;
	}

	private int deleteSessionInternal( String szSession, ExecRedisCmdErr  rtValue ) {
		String szCmd= "DEL " ;
		szCmd += szSession;
		int rslt = execCmd2Redis( szCmd, rtValue);
		return rslt;
	}

	//hiredis执行命令， 可以执行获取、删除等命令
	private int execCmd2Redis( String szCmd, ExecRedisCmdErr  rtValue ) {		
		// HDEL DEL
		if (szCmd.isEmpty()) {
			return -1;
		}
		String keys[] = szCmd.split(" ");
		String cmd = keys[0];

		Jedis sc = null;
		boolean broken = false;
		try {
			sc = RedisConnPool.getJedis();
			switch (cmd) {
			case "HDEL":
				long retv = sc.hdel(keys[1], keys[2]);
				break;
			case "DEL":
				long retv1 = sc.del(keys[1]);
				break;
			}
		} catch (JedisConnectionException e) {
			LOGGER.error(e.getMessage(), e);
			rtValue.setSzErrorCodeStr(e.getMessage());
			rtValue.setErrorCode(-1);
			broken = true;
			return -1;
		} finally {
			RedisConnPool.returnJedis(sc, broken);
		}

		return 0;
	
	}
	//hiredis执行命令，用于获取数据库中，单条String类型的值
	private int execCmd2Redis( String szCmd, StringBuffer  infoValue, ExecRedisCmdErr  rtValue ) {
		{
			//HGET LPOP HDEL			
			if(szCmd.isEmpty())
			{
				return -1;
			}
			String keys[]=szCmd.split(" ");
			String cmd=keys[0];
			
			Jedis sc = null;
			boolean broken = false;
			try {
				sc = RedisConnPool.getJedis();
			switch (cmd) {
			case "HGET":
				String infoV= sc.hget(keys[1], keys[2]);
				infoValue.delete(0, infoValue.length());
				infoValue.append(infoV);		
			case "LPOP":
				String infoV1=sc.lpop(keys[1]);
				infoValue.delete(0, infoValue.length());
				infoValue.append(infoV1);
			}
			} catch (JedisConnectionException e) {
				LOGGER.error(e.getMessage(), e);				
				rtValue.setSzErrorCodeStr(e.getMessage());
				rtValue.setErrorCode(-1);
				broken = true;
				return -1;
			} finally {
				RedisConnPool.returnJedis(sc, broken);
			}					
		}
		return 0;
	}
	//hiredis执行命令，用户获取数据库中单挑unsigned long 类型的值
//	private int execCmd2Redis( String szCmd, long  ulValue, ExecRedisCmdErr  rtValue ) {
//		return 0;
//	}
	//去重
	private static <T> List<T> removeDuplicate(final List<T> list) {
		 return Lists.newArrayList(Sets.newLinkedHashSet(list));
		}
	private int getLongTypeSetFromRedisIn( String szCmd, List<Long>  list, StringBuffer szIndex, ExecRedisCmdErr  rtValue ) {
		list.clear();	
		szIndex.delete(0, szIndex.length());		
		Jedis sc = null;
		boolean broken = false;
		try {
			sc = RedisConnPool.getJedis();
			String[] keys=szCmd.split(" ");				
			ScanResult<String> values=sc.sscan(keys[1], szIndex.toString());
			
			List<String> datas=values.getResult();
			if(datas.size()>0)
			{
				for ( int i = 0; i < datas.size(); i ++  )
				{
					list.add(Long.parseLong(datas.get(i)));
				}
			}			
			szIndex.append(values.getCursor());
			return 0;
		} catch (JedisConnectionException e) {
			LOGGER.error(e.getMessage(), e);				
			rtValue.setSzErrorCodeStr(e.getMessage());
			rtValue.setErrorCode(-1);
			broken = true;							
			szIndex.append(0);
		} finally {
			RedisConnPool.returnJedis(sc, broken);
		}
		return -1;			
	}


	@Override
	public int getGrpMemberFromRedisByGrpId(long ulGroupId,
			List<Long> memberList, ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
//		Jedis sc = null;
//		boolean broken = false;
//		try {
//			sc = RedisConnPool.getJedis();
//			// {"id":1,"optype":"insert"}
////			JSONObject json = new JSONObject();
////			json.put("table", "user");
////			json.put("id", user.getId());
////			if(optType==0)
////			{
////				json.put("optype", "insert");
////			}
////			else
////			{
////				json.put("optype", "update");
////			}
//			sc.lpush(RedisKeyProperties.sync_db, "666");			
//			return 1;
//		} catch (JedisConnectionException e) {
//			LOGGER.error(e.getMessage(), e);
//			broken = true;
//		} finally {
//			RedisConnPool.returnJedis(sc, broken);
//		}
		
		memberList.clear();
		String szGroupId="";
		szGroupId=String.format("%lu", ulGroupId);
		
		String szCmd="LRANGE group:";	//群组在list链表中存储
		szCmd += szGroupId;						//群组的key值为 user:%d:groups  %d是群组ID
		szCmd += ":users 0 -1";					//获取全部的memberid
		int rslt = getLongTypeListsFromRedis( szCmd, memberList, rtValue );
		return rslt;
	}
	@Override
	public int getSubscriber(long ulUserId, List<Long> subscUserIdList,
			ExecRedisCmdErr rtValue, String strDeviceType) {
		// TODO Auto-generated method stub
		subscUserIdList.clear();		
		String szPreSubCmd="sscan subscriber:";
		String szUserId=String.valueOf(ulUserId);
		
		//查找订阅 ulUserId 的用户
		String szCmd= szPreSubCmd;
		szCmd += strDeviceType;
		szCmd += ":";
		szCmd += szUserId;
		szCmd += ":users";
		int rslt = getLongTypeSetFromRedis( szCmd, subscUserIdList, rtValue );
		if ( rslt != 0 )
		{
			subscUserIdList.clear();
			return -1;
		}
		

		//查找 群组和部门的逻辑相同， 首先查找 ulUserId 所在的 群组/部门， 然后查找 订阅这些 群组/部门 的用户

		List<String> szMidCmdList = new ArrayList<String>();
		// 	szMidCmdList.push_back( "users" );			//被订阅的人
		szMidCmdList.add( "groups" );			//被订阅的群组
		szMidCmdList.add( "depts" );			//被订阅的部门

		String szPreUserCmd = "LRANGE user:";

		
		for (int i = 0; i < szMidCmdList.size(); i++) {	
			//查找 ulUserId 所在的 群组/部门
			String szMidCmd = szMidCmdList.get(i);
			szCmd=szPreUserCmd;
			szCmd += szUserId;
			szCmd += ":";
			szCmd += szMidCmd;
			szCmd += " 0 -1";
			List<Long> lists =  new ArrayList<Long>();
			int rslt1 = getLongTypeListsFromRedis( szCmd, lists, rtValue );
			if ( rslt1 != 0 )
			{
				subscUserIdList.clear();
				return -1;
			}

			//查找 订阅这些 群组/部门 的用户			
			for (int j = 0; j < lists.size(); j++) {
				long cId = lists.get(j);
				String szCId="";
				szCId=szCId.format("%lu",cId);
				String szCmd1=szPreSubCmd;
				szCmd1 += strDeviceType;
				szCmd1 += ":";
				szCmd1 += szCId;
				szCmd1 += ":";
				szCmd1 += szMidCmd;
				rslt = getLongTypeSetFromRedis( szCmd1, subscUserIdList, rtValue );
				if ( rslt != 0 )
				{
					subscUserIdList.clear();
					return -1;
				}
			}
		}
		Collections.sort(subscUserIdList);
		subscUserIdList=removeDuplicate(subscUserIdList);
		return 0;
	}
	@Override
	public int getUserSubscriber(long ulUserId, List<Long> subscUserIdList,
			ExecRedisCmdErr rtValue, String strDeviceType, String strType) {
		// TODO Auto-generated method stub
		
		subscUserIdList.clear();

		String szPreSubCmd="sscan subscriber_user:";
		
		String szUserId="";
		szUserId=String.format("%lu", ulUserId);
		//查找 ulUserId 订阅的用户		
		szPreSubCmd += strDeviceType;
		szPreSubCmd += ":";
		szPreSubCmd += szUserId;
		int rsltuser = getLongTypeSetFromRedis( szPreSubCmd + ":"+strType, subscUserIdList, rtValue );
		if ( rsltuser != 0 )
		{
			subscUserIdList.clear();
			return -1;
		}
		return 0;
	}
	@Override
	public int getUserLoginInfo(long ulUserId, StringBuffer loginInfo,
			ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szUserId="";
		szUserId=String.format("%lu", ulUserId);
		String szCmd= "HGET presence ";
		szCmd += szUserId;
		int rslt = execCmd2Redis( szCmd, loginInfo, rtValue );
		return rslt;
	}
	@Override
	public int getNotifyContent(Map<String, String> hashMap,
			ExecRedisCmdErr rtValue) {
		//最好不要使用HGETALL这种命令，在数据量大的时候，会造成redis阻塞
		/*std::string szCmd = "HGETALL notify";
		int rslt = getStringTypeHashsFromRedis( szCmd, hashMap, rtValue );
		return rslt;*/
		hashMap.clear();
		StringBuffer  szIndex=new StringBuffer ("0");
		do 
		{
			String szCmd= "HSCAN notify ";
			szCmd += szIndex.toString();
			int rslt = getStringTypeHashsFromRedis( szCmd, hashMap, szIndex, rtValue );
			if (rslt != 0) {
				LOGGER.warn("CSyncRedis::getNotifyContent getStringTypeHashsFromRedis rslt:" +rslt);
			}
		} while ( szIndex.toString() != "0" );
		return 0;
	}
	@Override
	public int delNotifyContent(String hashKeys, ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szCmd = "HDEL notify " + hashKeys;
		int rslt = execCmd2Redis( szCmd, rtValue );
		return rslt;
	}
	@Override
	public int getAppMsgContent(Map<String, String> hashMap,
			ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		hashMap.clear();
		StringBuffer szIndex=new StringBuffer( "0" );
		do 
		{
			String szCmd="HSCAN qx_pushnotify ";
			szCmd += szIndex.toString();
			int rslt = getStringTypeHashsFromRedis( szCmd, hashMap, szIndex, rtValue );
			if (rslt != 0) {				
				LOGGER.warn("CSyncRedis::getAppMsgContent getStringTypeHashsFromRedis rslt:"+rslt);
			}
		} while ( szIndex.toString() != "0" );
		return 0;
	}
	@Override
	public int delAppMsgContent(String hashKeys, ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szCmd = "HDEL qx_pushnotify " + hashKeys;
		int rslt = execCmd2Redis( szCmd, rtValue );
		return rslt;
	}
	@Override
	public int getSMSMsgContent(Map<String, String> hashMap,
			ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		hashMap.clear();
		StringBuffer szIndex=new StringBuffer( "0" );
		do 
		{
			String szCmd="HSCAN SMS_msg_uplink ";
			szCmd += szIndex;
			int rslt = getStringTypeHashsFromRedis( szCmd, hashMap, szIndex, rtValue );
			if (rslt != 0) {
				LOGGER.warn("CSyncRedis::getSMSMsgContent getStringTypeHashsFromRedis rslt:" +rslt);
			}
		} while ( szIndex.toString() != "0" );
		
		return 0;
	}
	@Override
	public int delSMSMsgContent(String hashKeys, ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szCmd = "HDEL SMS_msg_uplink " + hashKeys;
		int rslt = execCmd2Redis( szCmd, rtValue );
		return rslt;
	}
	@Override
	public int getMsgContent(int msgType, List<String> msgList,
			ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		msgList.clear();
		String szCmd = "LRANGE ";
		if (msgType == 0) {
			szCmd += "ims_msg_hist ";
		} else if (msgType == 1) {
			szCmd += "group_msg_hist ";
		} else {
			rtValue.setSzErrorCodeStr("Invalid message type!");
			rtValue.setErrorCode(-1);
			return -1;
		}
		szCmd += "0 -1";
		{

			List<String> values = new ArrayList<String>();
			{

				Jedis sc = null;
				boolean broken = false;
				try {
					sc = RedisConnPool.getJedis();
					String[] keys = szCmd.split(" ");
					values = sc.lrange(keys[1], Long.parseLong(keys[2]),
							Long.parseLong(keys[3]));
				} catch (JedisConnectionException e) {
					LOGGER.error(e.getMessage(), e);
					rtValue.setSzErrorCodeStr(e.getMessage());
					rtValue.setErrorCode(-1);
					broken = true;
				} finally {
					RedisConnPool.returnJedis(sc, broken);
				}
				if (values.isEmpty()) {
					return -1;
				}

				for (int i = 0; i < values.size(); i++) {
					String szMsg = values.get(i);
					msgList.add(szMsg);
				}
				return 0;
			}
		}
	}
	@Override
	public int getAllDeptId(List<Long> deptIdList, ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szCmd="HKEYS dept";
		int rslt = getAllLongTypeHashKeysFromRedis( szCmd, deptIdList, rtValue );
		return rslt;
	}
	@Override
	public int getDeptMemberIdByDeptId(long ulDeptId,
			List<Long> deptMemberIdList, ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		deptMemberIdList.clear();
		String szDeptId="";
		szDeptId=String.format("%lu", ulDeptId );
		String szCmd="LRANGE dept:";
		szCmd += szDeptId;
		szCmd += ":users 0 -1";
		int rslt = getLongTypeListsFromRedis( szCmd, deptMemberIdList, rtValue );
		return rslt;
	}
	@Override
	public int getDeptIdByDomainId(String strDomainid, List<Long> deptIdList,
			ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		deptIdList.clear();
		String szCmd="LRANGE domain:depts:";
		szCmd += strDomainid;
		szCmd += " 0 -1";
		int rslt = getLongTypeListsFromRedis( szCmd, deptIdList, rtValue );
		return rslt;
	}
	@Override
	public int getUserIdByTelphone(String telphone, StringBuffer strUserId,
			ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szCmd="HGET phone_id ";
		szCmd += telphone;		
		int rslt = execCmd2Redis( szCmd, strUserId, rtValue );
		return rslt;
	}
	@Override
	public int getUserInfoByUserId(long ulUserId, StringBuffer strUserInfo,
			ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szCmd= "HGET user ";
		String szUserId="";
		szUserId=String.format("%lu", ulUserId);
		szCmd += szUserId;
		int rslt = execCmd2Redis( szCmd, strUserInfo, rtValue );
		return rslt;
	}
	@Override
	public int getUserInfoByUserId(String szUserId, StringBuffer szUserInfo,
			ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szCmd="HGET user ";
		szCmd += szUserId;
		int rslt = execCmd2Redis( szCmd, szUserInfo, rtValue );
		return rslt;
	}
	@Override
	public int getMobileNumByGroupId(long ulGroupId, StringBuffer strMobileNum,
			ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szGroupId="";
		szGroupId=String.format("%lu", ulGroupId);
		String szCmd = "HVALS group:";
		szCmd += szGroupId;
		szCmd += ":phones";
		int rslt = getStringValsHashsFromRedis( szCmd, strMobileNum, rtValue );
		return rslt;
	}
	@Override
	public int getUserSession(String userid, StringBuffer szSession,
			ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szCmd="HGET usersession ";
		szCmd += userid;
		int rslt = execCmd2Redis( szCmd, szSession, rtValue );
		return rslt;
	}
	@Override
	public int getIosTokenByUserId(String szUserId, StringBuffer szIosToken,
			ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szCmd="HGET iostoken ";
		szCmd += szUserId;
		int rslt = execCmd2Redis( szCmd, szIosToken, rtValue );
		return rslt;
	}
	@Override
	public int getAllIosTokenUserIds(List<Long> userIdList,
			ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		userIdList.clear();
		String szCmd="HKEYS iostoken";
		int rslt = getAllLongTypeHashKeysFromRedis( szCmd, userIdList, rtValue );
		return rslt;
	}
	@Override
	public int getFreeSwitchJson(List<String> fsListJson,
			ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		fsListJson.clear();
		String szCmd = "LRANG SWITCH.Event 0 -1";
		{

			List<String> values = new ArrayList<String>();
			{

				Jedis sc = null;
				boolean broken = false;
				try {
					sc = RedisConnPool.getJedis();
					String[] keys = szCmd.split(" ");
					values = sc.lrange(keys[1], Long.parseLong(keys[2]),
							Long.parseLong(keys[3]));
				} catch (JedisConnectionException e) {
					LOGGER.error(e.getMessage(), e);
					rtValue.setSzErrorCodeStr(e.getMessage());
					rtValue.setErrorCode(-1);
					broken = true;
				} finally {
					RedisConnPool.returnJedis(sc, broken);
				}
				if (values.isEmpty()) {
					return -1;
				}

				for (int i = 0; i < values.size(); i++) {
					String szMsg = values.get(i);
					fsListJson.add(szMsg);
				}
				return 0;
			}
		}
	}
	@Override
	public int getFreeSwitchJson(StringBuffer fsJson, ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szCmd="LPOP SWITCH.Event";
		int rslt = execCmd2Redis( szCmd, fsJson, rtValue );
		return rslt;
	}
	//@Override
//	public int initRedisConn(String server, int port) {
//		// TODO Auto-generated method stub
//		return 0;
//	}
	@Override
	public int deleteUserSession(String userid, StringBuffer strSessionId,
			ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		//首先获取用户的session
		StringBuffer szUserSession=new StringBuffer("");
		int rslt = getUserSession( userid, szUserSession ,rtValue );
		if ( rslt == -1 )
		{
			return rslt;
		}

		// 如果不相同，不删
		if (szUserSession != strSessionId)
			return rslt;

		//然后从usersession中删除这个用户
		rslt = deleteUserSessionInternal( userid, rtValue );
		if ( rslt == -1 )
		{
			return rslt;
		}

		//再删除session里面的
		String szSession="session:";
		szSession += szUserSession;
		rslt = deleteSessionInternal( szSession, rtValue );
		return rslt;
	}
	@Override
	public int deletePreDelSession(String strSessionId, ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szCmd = "HDEL predelsession " + strSessionId;
		int rslt = execCmd2Redis( szCmd, rtValue );
		return rslt;
	}
	@Override
	public int getPreDelSession(String szSession, StringBuffer userid,
			ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szCmd="HGET predelsession ";
		szCmd += szSession;
		int rslt = execCmd2Redis( szCmd, userid, rtValue );
		return rslt;
	}
	@Override
	public int getBroadcastMsgByCount(String[] strMsgArray, int ulCount,
			ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szCount="";
		szCount=String.format("%u", ulCount);
		String szCmd = "LRANGE ims_broadcast ";
		szCmd += "0 ";
		szCmd += szCount;
		int rslt = getStringTypeListsFromRedisByCount( szCmd, strMsgArray, ulCount, rtValue );
		return rslt;
	}
	@Override
	public int getBroadcastMsg(StringBuffer strMsg, ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szCmd = "LPOP ims_broadcast";
		int rslt = execCmd2Redis( szCmd, strMsg, rtValue );
		return rslt;
	}
	@Override
	public int getPreSendSmsMsg(StringBuffer szMmsMsg, ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szCmd = "LPOP sms_presend";
		int rslt = execCmd2Redis( szCmd, szMmsMsg, rtValue );
		return rslt;
	}
	@Override
	public int getIosPushMsg(StringBuffer strMsg, ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		String szCmd = "LPOP ims_msg_ios_push";
		int rslt = execCmd2Redis( szCmd, strMsg, rtValue );
		return rslt;
	}
	@Override
	public int getGroupStatusErr(List<String> szList, ExecRedisCmdErr rtValue) {
		// TODO Auto-generated method stub
		szList.clear();
		String szCmd="LRANGE group_msg_hist_status_err 0 -1";
		int rslt = getStringTypeListsFromRedis( szCmd, szList, rtValue );
		return rslt;
	}

}
